package com.sneakxy.actions;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.beetl.core.exception.BeetlException;

import com.sneakxy.beetl.ActionTemplate;
import com.sneakxy.beetl.TemplateDir;
import com.sneakxy.beetl.TemplateFile;
import com.sneakxy.config.Config;
import com.sneakxy.utils.JAXBUtils;
import com.sneakxy.utils.StringUtilsExt;

public interface Action {

	public void execute(CommandLine command, Options options) throws Exception;
	
	default ActionTemplate createActionTemplate(CommandLine command, Options options) throws IOException {
		ActionTemplate template = null;
		if(command.hasOption("t")) {
			String path = command.getOptionValue("t", "./template/");
			template = new ActionTemplate(new File(path)); 
		} else {
			template = new ActionTemplate("/template/");
		}
		if(!template.getFile().exists() || !template.getFile().isDirectory()) {
			throw new NullPointerException("缺少模板.");
		}
		return template;
	}
	
	default Config createConfig(CommandLine command, Options options) throws FileNotFoundException, IOException {
		String path = "config.xml";
		ClassLoader cs = this.getClass().getClassLoader();
		URL url = cs.getResource(path);
		if(url == null) {
			//兼容以前的
			url = cs.getClass().getResource(path);
		}
		String configXml = command.getOptionValue("config", url.getFile());
		String xml = IOUtils.toString(new FileInputStream(new File(configXml)), Charset.forName("UTF-8"));
		Config config = JAXBUtils.fromXML(xml, Config.class);
		if(!StringUtils.endsWith(config.getPath(), File.separator)) {
			config.setPath(StringUtils.join(config.getPath(), File.separator));
		}
		return config;
	}
	
	default void renderDirectory(File dir, TemplateDir tmpDir) throws BeetlException, FileNotFoundException {
		renderFiles(dir, tmpDir);
		File[] dirs = dir.listFiles((File file) -> {
			return file.isDirectory() && isAllowed(file.getName());
		});
		TemplateDir cTmpDir = null;
		for(File cdir: dirs) {
			cTmpDir = new TemplateDir(StringUtils.join(tmpDir.getKey(),"/", cdir.getName()), 
					StringUtils.join(tmpDir.getPath(),  StringUtilsExt.replace(cdir.getName(), getNameFormatter()), File.separator));
			cTmpDir.mkdirs();
			renderDirectory(cdir, cTmpDir);
		}
	}
	
	default void renderFiles(File dir, TemplateDir tmpDir) throws BeetlException, FileNotFoundException {
		File[] files = dir.listFiles((File file) -> {
			return file.isFile() && isAllowed(file.getName());
		});
		for(File file: files) {
			new TemplateFile(this.getActionTemplate(), file.getName(), StringUtilsExt.replace(file.getName(), getNameFormatter()), tmpDir).write(this.getWriteParams());
		}
	}
	
	default Map<String, Object> getWriteParams() {
		return null;
	}
	
	default Map<String, Object> getNameFormatter() {
		return null;
	}
	
	default ActionTemplate getActionTemplate() {
		return null;
	}
	
	default boolean isAllowed(String filename) {
		return false;
	};
	
}
